package GA_Test;

import 多无人机架次.*;

import java.sql.Time;
import java.util.ArrayList;
import java.util.Random;
import java.util.TimerTask;

/**
 * NAME【不同车辆之间节点交换算子】   DATE【2020.12.29】   FUNCTION【个体内不同车辆之间进行节点交换】
 *
 * Input：种群、当前退火温度   Output：执行完交叉算子后的种群
 *
 * Methods：
 * 1、主方法： 遍历个体--个体内部交换--个体内部交换后重生成--判断是否接受新个体
 * 2、交换方法： 实现节点交换功能
 * 3、重规划方法：用来针对交换算法执行后的个体 进行路径重新生成
 * 4、判断方法：判断是否接受新个体
 */
public class Operators_different_1_1 {
    static SpeciesPopulation different_change(SpeciesPopulation new_list, float now_tem ){
        //遍历个体   遍历个体即对所有种群中的个体执行该算子的操作  即体现本算法的并行步骤
        SpeciesPopulation new_pop = new SpeciesPopulation(); //生成一个待完善的种群
        big:
        for (int i = 0; i < new_list.specPopu.size(); i++) {
            SpeciesIndividual old_individual =new_list.specPopu.get(i);//拿出一个个体
            SpeciesIndividual old_copy = old_individual.clone();//把这个个体先存下来  如果不接受新个体 就用这个个体
            double old_runtime = old_individual.individual_runtime;
            SpeciesIndividual new_individual = exchange(old_individual);//返回一个个体
            //这里利用模拟退火规则去判断是否接受这个新个体
            new_individual.calFitness();
            double new_runtime = new_individual.individual_runtime;
               if (new_runtime <= old_runtime) { //如果新个体的时间优于旧个体 那么就接受新个体
                    new_pop.add(new_individual);
                    continue big;//复制完当前这个 更好的个体 继续处理种群内其他个体
               } else { //如果不是的话 利用模拟退火规则接受这个个体
                    Random random = new Random();
                    double value = Math.exp((new_runtime - old_runtime) / now_tem);
                    double r = random.nextInt(1);//生成一个0-1之间的随机数
                    if (r > value) {//如果随机生成的概率大于这个 模拟退火的概率值  那么就接受这个劣解
                         new_pop.add(new_individual);
                         continue big;
                    } else {//这里本来是还原个体 现在不需要还原 因为如果没有发生优化 个体在交叉时就进行了还原 即只要交叉 必定是优化过的
                         new_pop.add(old_copy); //把之前复制的那个备份个体 加进去
                         continue big;
                    }
               }

        }
        return new_pop;
    }

    private static SpeciesIndividual exchange(SpeciesIndividual now_individual) { //对这个个体进行什么操作呢
        //这个方法用来对路径进行访问节点交换
        ArrayList<Object> truck_collection = now_individual.TruckGenes;
        ArrayList<Object> drone_collection = now_individual.DroneGenes;
        Integer a1 = 0;
        Integer a2 = 0;
        Random r = new Random();
        while (true){ //从车辆路径里随机选出两个不同的路径
            a1 = r.nextInt(truck_collection.size());
            a2 = r.nextInt(truck_collection.size());
            if(a1 != a2){
                break;
            }
        }
        //这里的交叉原则就采用随机撞击   每次可以进行5次交叉  选择5次交叉中  结果较好的那一次作为交叉的最终结果
        ArrayList<Integer> t1 = (ArrayList<Integer>) truck_collection.get(a1);       //拿出第一辆车
        ArrayList<Integer> t2 = (ArrayList<Integer>) truck_collection.get(a2);       //拿出第二辆车
        ArrayList<Integer> d1 = (ArrayList<Integer>) drone_collection.get(a1);       //拿出第一辆车对应的无人机
        ArrayList<Integer> d2 = (ArrayList<Integer>) drone_collection.get(a2);       //拿出第二辆车对应的无人机
        ArrayList<Integer> t1_customers = getCustomers(t1,d1);                       //车1 服务顾客集
        ArrayList<Integer> t2_customers = getCustomers(t2,d2);                       //车2 服务顾客集
        double best_time = TimeCount.timeCount(t1,d1) + TimeCount.timeCount(t2,d2);  //将所选择的两条线路的初始运行时间作为最优值
        Random random = new Random();
        for(int i = 0;i<20;i++) {
            Integer t1_change_point = t1_customers.get(random.nextInt(t1_customers.size())); //从车1 顾客中随机选择一个
            Integer t2_change_point = t2_customers.get(random.nextInt(t2_customers.size()));

            t1_customers.remove(t1_change_point);
            t1_customers.add(t2_change_point);
            t2_customers.remove(t2_change_point);
            t2_customers.add(t1_change_point); //进行交换
            Object[] t1_and_d1 = reProduce(t1_customers);// 交换后 路径重新生成
            Object[] t2_and_d2 = reProduce(t2_customers);
            ArrayList<Object> truck1 = (ArrayList<Object>) t1_and_d1[0];
            ArrayList<Object> drone1= (ArrayList<Object>) t1_and_d1[1];
            ArrayList<Object> truck2 = (ArrayList<Object>) t2_and_d2[0];
            ArrayList<Object> drone2 = (ArrayList<Object>) t2_and_d2[1];
            if (truck1.size() == 1 && truck2.size() == 1) {
                //这里如果两条路径重生后 均为1  则将重生后的路径覆盖到原来的路径上去
                ArrayList<Integer> tt1 = (ArrayList<Integer>) truck1.get(0);
                ArrayList<Integer> dd1 = (ArrayList<Integer>) drone1.get(0);
                ArrayList<Integer> tt2 = (ArrayList<Integer>) truck2.get(0);
                ArrayList<Integer> dd2 = (ArrayList<Integer>) drone2.get(0);
                truck_collection.set(a1,tt1);
                drone_collection.set(a1,dd1);
                truck_collection.set(a2,tt2);
                drone_collection.set(a2,dd2);
                double truck1_time = TimeCount.timeCount(tt1,dd1);
                double truck2_time = TimeCount.timeCount(tt2,dd2);
                double now_time = truck1_time + truck2_time;  //新路径的时间和
                if(now_time<best_time){
                    break;
                }else{
                    continue;
                }
            } else { //否则的话 继续循环
                t1_customers.remove(t2_change_point);
                t1_customers.add(t1_change_point);
                t2_customers.remove(t1_change_point);
                t2_customers.add(t2_change_point); //进行还原
                continue;
            }

        }
        return now_individual;
    }

    public static Object[] reProduce(ArrayList<Integer> customers) {
                Object[] obj = new Object[2];
                ArrayList<Object> truck_hub = new ArrayList<>(); //车辆行驶路径集合
                ArrayList<Object> drone_hub = new ArrayList<>();//无人机行驶路径集合
                ArrayList<Integer> w = new ArrayList<Integer>();
                double D = GAData.distanceDrone;//无人机续航距离
                int M = GAData.capacityDrone;//无人机载重
                int Q = GAData.capacityTruck;//车辆载重
                for (Integer c = 0; c < customers.size(); c++) { //初始将所有的顾客节点 加入未访问节点集w
                    w.add(customers.get(c));//把customers集合中的所有顾客点作为输出  放到所有未访问节点集合w中
                }
                car:
                for (int i = 0; i < 20; i++) {//车辆选择循环
                    //初始化w未访问节点集 f已访问节点集 RT车辆访问节点 RU无人机访问节点  dronetrip是当前车辆的无人机线路集
                    ArrayList<Object> hub = new ArrayList<>(100);//hub是一个中转的集合  初始的长度设为100
                    for (int j = 0; j < 10; j++) {
                        hub.add(new ArrayList<Integer>());
                    }
                    ArrayList<Object> drone_trip = new ArrayList<Object>(100);
                    ArrayList<Integer> f = new ArrayList<Integer>();
                    ArrayList<Integer> RT = new ArrayList<Integer>();
                    ArrayList<Integer> RU = new ArrayList<Integer>();
                    int j;double l = 0.00;ArrayList<Integer> s = null;
                    if(w.size()>1) {
                        //这里不用随机 就用传统的方法去生成车辆路径
                        Integer theFirstpoint = Distance.wDistance1(0, w);
                        w.remove(theFirstpoint);
                        Integer theSecondPoint = Distance.wDistance1(theFirstpoint, w);

                        w.remove(theSecondPoint);
                        l = GAData.disCollection[theFirstpoint][theSecondPoint];
                        //进行对应距离点的 加入与移除操作
                        RU.add(theFirstpoint);
                        RT.add(theFirstpoint);
                        RT.add(theSecondPoint);
                        f.add(theFirstpoint);
                        f.add(theSecondPoint);
                        if(w.size()==0){
                            PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            break car;
                        }
                        s = Distance.sProduce(w, RU);// 获取s
                        //如果 s 没有获取成功   并且 w中只有一个数  那么说明当前w中这个数 不满足某约束  则将其加入RT中 打印输出
                        if(s.size()==0 && w.size()==1){
                            RT.add(w.get(0));
                            PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                            //sum_time += time;
                            break car;
                        }
                    }else if(w.size()==1){
                        RT.add(w.get(0));
                        PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                        //sum_time += time;
                        break car;
                    }else if(w.size()==0){
                        break car;
                    }
                    sdrone:
                    for (j = 0; j < s.size(); j++) {
                        RU.add(s.get(j));
                        w.remove(s.get(j));
                        f.add(s.get(j));
                        double Ud = Distance.sumUd(RU);
                        int Uzz = Capcity.Uzz(RU);
                        int rucount = RU.size();
                        //******************************************************************************距离判断分支 2
                        if (Ud >= D && rucount == 2) {

                            Integer ru_last = RU.get(RU.size() - 1);
                            Integer rt_last = RT.get(RU.size() - 1);
                            w.add(ru_last);
                            f.remove(ru_last);
                            RU.clear();
                            RU.add(RT.get(RT.size() - 1));
                            Integer w_closest = Distance.wDistance1(rt_last, w);
                            RT.add(w_closest);
                            l = GAData.disCollection[rt_last][w_closest];
                            w.remove(w_closest);
                            f.add(w_closest);
                            int f_demand = Capcity.fD(f);//已访问节点中 的需求

                            if (f_demand < Q) {
                                if (w.size() > 0) {
                                    s = Distance.sProduce(w, RU);
                                    if(s.size()==0 && w.size()==1){//这个判断比较关键   决定的是 所剩下的 未访问节点 均无法再被无人机访问的情况
                                        RT.add(w.get(0));
                                        PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                        //sum_time += time;
                                        break car;
                                    }
                                    j = -1;//从0 开始 遍历新的s
                                    continue sdrone;
                                } else {
                                    PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    break car;
                                }
                            } else if (f_demand == Q) {//需要换辆车
                                if (w.size() > 0) {

                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    if(w.size()==1){
                                        int k = 0;
                                    }
                                    continue car;
                                } else {
                                    PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    break car;
                                }
                            } else if (f_demand > Q) {
                                RT.remove(RT.get(RT.size() - 1));
                                w.add(RT.get(RT.size() - 1));
                                f.remove(RT.get(RT.size() - 1));
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                if(w.size()==1){
                                    int k = 0;
                                }
                                continue car;
                            }
                            //**********************************************************************距离判断分支 1
                        } else if (Ud == D && rucount > 2) {
                            RT.add(RU.get(RU.size() - 1));  //将RU内最后一个点加入RT
                            drone_trip = DroneTripUpdate.Method(hub, RU); //将当前RU存在 drone trip里
                            RU.clear();
                            //寻找未访问节点集w中距离RT内最后一个点 距离最近的两个点，并加入RT 纠正错误：应该是最近的一个点  与 当前这个最近点 最近的点
                            if (w.size() > 1) {
                                Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                                RT.add(the_closest);w.remove(the_closest);
                                Integer the_second = Distance.wDistance1(the_closest, w);
                                RT.add(the_second);w.remove(the_second);
                                //将RU内的节点清除掉   并将上述theclosest点 加入RU内 作为新的起飞点
                                RU.add(the_closest);
                                f.add(the_closest);
                                f.add(the_second);
                                l = GAData.disCollection[the_closest][the_second];
                                //下列为 一模一样的步骤
                                int f_demand = Capcity.fD(f);//已访问节点中 的需求
                                if (f_demand < Q) {
                                    if (w.size() > 0) {
                                        s = Distance.sProduce(w, RU);
                                        j = -1;
                                        continue sdrone;
                                    } else {//加了两个点到RT   但是满足总体载重需求  所以直接打印就好
                                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                        //sum_time += time;
                                        if(RT.size()==1){
                                            Integer kkk=1;
                                        }
                                        break car;
                                    }

                                } else if (f_demand == Q) { //加了点后  刚好达到载重要求   打印出当前的路径 换车
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    if(RT.size()==1){
                                        int k =0;
                                    }
                                    continue car;
                                } else {
                                    RT.remove(the_closest);
                                    RT.remove(the_second);
                                    w.add(the_closest);
                                    w.add(the_second);
                                    f.add(the_closest);
                                    f.add(the_second);
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    if(w.size()==1){
                                        int k = 0;
                                    }
                                    continue car;
                                }
                            } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                                PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                                break car;// 跳出大循环
                            } else if (w.size() == 1) {
                                PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;
                            }
                            //********************************************************距离判断分支3
                        } else if (Ud > D && rucount > 3) {//
                            RT.add(RU.get(RU.size() - 2));//将RU中倒数第二个点加入RT
                            w.add(RU.get(RU.size() - 1));
                            f.remove(RU.get(RU.size() - 1));//f 与 w 一增一减
                            RU.remove(RU.size() - 1);
                            drone_trip = DroneTripUpdate.Method(hub, RU);
                            RU.clear();// 保存完 RU后  将 RU清空
                            //********************************************************************
                            if (w.size() > 1) {

                                Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                                RT.add(the_closest);w.remove(the_closest);
                                Integer the_second = Distance.wDistance1(the_closest, w);
                                RT.add(the_second);w.remove(the_second);

                                RU.add(the_closest);//为下一个架次 设置起飞点
                                f.add(the_closest);
                                f.add(the_second);
                                l = GAData.disCollection[the_closest][the_second];
                                int f_demand = Capcity.fD(f);//已访问节点中 的需求

                                if (f_demand < Q) {
                                    if (w.size() > 0) {
                                        s = Distance.sProduce(w, RU);
                                        j = -1;
                                        continue sdrone;
                                    } else {//加了两个点到RT   但是满足总体载重需求  所以直接打印就好
                                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                        //sum_time += time;
                                        continue car;
                                    }

                                } else if (f_demand == Q) { //加了点后  刚好达到载重要求   打印出当前的路径 换车
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    if(w.size()==1){
                                        int k = 0;
                                    }
                                    continue car;
                                } else {
                                    RT.remove(the_closest);
                                    RT.remove(the_second);
                                    w.add(the_closest);
                                    w.add(the_second);
                                    f.add(the_closest);
                                    f.add(the_second);
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    if(w.size()==1){
                                        int k = 0;
                                    }
                                    continue car;
                                }
                            } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                                PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;// 跳出大循环
                            } else if (w.size() == 1) {
                                PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;
                            }
                        } else if (Ud > D && rucount == 3) {
                            Integer ru_last = RU.get(RU.size() - 1);
                            Integer ru_second = RU.get(RU.size() - 2);
                            RU.clear();
                            w.add(ru_last);
                            w.add(ru_second);
                            f.remove(ru_last);
                            f.remove(ru_second);
                            Integer rt_last = RT.get(RT.size() - 1);
                            RU.add(rt_last);//将rt内最后一个点设为ru中的新的起飞点
                            Integer w_closest = Distance.wDistance1(rt_last, w);
                            RT.add(w_closest);
                            l = GAData.disCollection[rt_last][w_closest];
                            w.remove(w_closest);
                            f.add(w_closest);

                            int f_demand = Capcity.fD(f);//已访问节点中 的需求
                            if (f_demand < Q) {
                                if (w.size() > 0) {
                                    s = Distance.sProduce(w, RU);
                                    j = -1;//从0 开始 遍历新的s
                                    continue sdrone;
                                } else {
                                    PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    break car;
                                }
                            } else if (f_demand == Q) {
                                if (w.size() > 0) {
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    continue car;
                                } else {
                                    PrintRoute.printRoute_w0(RT, RU,w, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    break car;
                                }
                            } else if (f_demand > Q) {
                                RT.remove(RT.get(RT.size() - 1));
                                w.add(RT.get(RT.size() - 1));
                                f.remove(RT.get(RT.size() - 1));
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                continue car;
                            }

                        } else if (Ud < D && Uzz == M && rucount > 2) {
                            //************************************************************载重判断分支1
                            RT.add(RU.get(RU.size() - 1));  //将RU内最后一个点加入RT
                            drone_trip = DroneTripUpdate.Method(hub, RU); //将当前RU存在 drone trip里
                            RU.clear();
                            //寻找未访问节点集w中距离RT内最后一个点 距离最近的两个点，并加入RT
                            if (w.size() > 1) {
                                Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                                RT.add(the_closest);w.remove(the_closest);
                                Integer the_second = Distance.wDistance1(the_closest, w);
                                RT.add(the_second);w.remove(the_second);
                                //将RU内的节点清除掉   并将上述theclosest点 加入RU内 作为新的起飞点
                                RU.add(the_closest);
                                //更新w 与 f   更新 l
                                f.add(the_closest);
                                f.add(the_second);
                                l = GAData.disCollection[the_closest][the_second];
                                //下列为 一模一样的步骤
                                int f_demand = Capcity.fD(f);//已访问节点中 的需求
                                if (f_demand < Q) {
                                    if (w.size() > 0) {
                                        s = Distance.sProduce(w, RU);
                                        j = -1;
                                        continue sdrone;
                                    } else {
                                        PrintRoute.printRoute_w0(RT, RU, w,drone_trip,obj,truck_hub,drone_hub);

                                    }

                                } else if (f_demand == Q) {
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    continue car;
                                } else {
                                    RT.remove(the_closest);
                                    RT.remove(the_second);
                                    w.add(the_closest);
                                    w.add(the_second);
                                    f.add(the_closest);
                                    f.add(the_second);
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    continue car;
                                }
                                w.add(RT.get(RT.size() - 1));
                                f.remove(RT.get(RT.size() - 1));
                                RT.remove(RT.size() - 1);
                                PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                continue car;
                            } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                                PrintRoute.printRoute_w0(RT, RU, w,drone_trip,obj,truck_hub,drone_hub);
                                break car;// 跳出大循环
                            } else if (w.size() == 1) {
                                PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                break car;
                            }
                        } else if (Ud < D && Uzz > M && rucount > 2) {
                            //*********************************************************载重判断分支3
                            RT.add(RU.get(RU.size() - 1));//将RU中倒数第一个点加入RT
                            drone_trip = DroneTripUpdate.Method(hub, RU);
                            RU.clear();// 保存完 RU后  将 RU清空
                            //********************************************************************
                            if (w.size() > 1) {

                                Integer the_closest = Distance.wDistance1(RT.get(RT.size() - 1), w);
                                RT.add(the_closest);w.remove(the_closest);
                                Integer the_second = Distance.wDistance1(the_closest, w);
                                RT.add(the_second);w.remove(the_second);

                                RU.add(the_closest);//为下一个架次 设置起飞点
                                f.add(the_closest);
                                f.add(the_second);
                                l =GAData.disCollection[the_closest][the_second];

                                int f_demand = Capcity.fD(f);//已访问节点中 的需求

                                if (f_demand < Q) {
                                    if (w.size() > 0) {
                                        s = Distance.sProduce(w, RU);
                                        j = -1;
                                        continue sdrone;
                                    } else {//加了两个点到RT   但是满足总体载重需求  所以直接打印就好
                                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                        //sum_time += time;
                                        break car;
                                    }

                                } else if (f_demand == Q) { //加了点后  刚好达到载重要求   打印出当前的路径 换车
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    continue car;
                                } else {
                                    RT.remove(the_closest);
                                    RT.remove(the_second);
                                    w.add(the_closest);
                                    w.add(the_second);
                                    f.add(the_closest);
                                    f.add(the_second);
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;
                                    if(w.size()==1){
                                        int k = 0;
                                    }
                                    continue car;
                                }
                            } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                                PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;// 跳出大循环
                            } else if (w.size() == 1) {
                                PrintRoute.printRoute_w1(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;
                            }

                        }else if(Ud<D && Uzz>=M && rucount==2) {//如果无人机路径里 只有两个点但是 载重已经超负荷
                            RT.add(RU.get(1));//把这个点 送给 车
                            RU.remove(1);//从无人机中移除
                            if(w.size()>0){
                                s = Distance.sProduce(w, RU);//重新生成 s
                                j=-1;
                                continue sdrone;//重新为无人机寻找 客户点
                            }else{
                                PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                break car;
                            }

                        }else if (Ud < D && Uzz < M && Ud >= 1.5 * l) {
                            //*****************************************************1.5l判断 分支 1
                            if (w.size() > 0) {  // 如果未访问的节点数目大于1
                                Integer rt_last = RT.get(RT.size() - 1);
                                Integer rt_last_closest = Distance.wDistance1(rt_last, w);
                                RT.add(rt_last_closest);
                                w.remove(rt_last_closest);
                                f.add(rt_last_closest);
                                l = GAData.disCollection[rt_last][rt_last_closest];//当前RU内起飞点为起点
                                //下列为 一模一样的步骤

                                int f_demand = Capcity.fD(f);//已访问节点中 的需求
                                if (f_demand < Q) {
                                    if (w.size() > 0) {
                                        s = Distance.sProduce(w, RU);
                                        j = -1;//从0 开始 遍历新的s
                                        continue sdrone;
                                    } else { //w.size == 0
                                        if(RU.size()==1){
                                            PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub); //sum_time += time;
                                            break car;
                                        }else if(RU.size()==2){
                                            RU.add(RT.get(RT.size()-1));
                                            drone_trip = DroneTripUpdate.Method(hub, RU);
                                            PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                            //sum_time += time;
                                            break car;
                                        }else if(RU.size()>=3){
                                            RT.add(RU.get(RU.size()-1));//将RU内最后一个节点作为降落点
                                            drone_trip = DroneTripUpdate.Method(hub, RU);//
                                            PrintRoute.printRoute(RT,RU,drone_trip,obj,truck_hub,drone_hub);
                                            //sum_time += time;
                                            break car;
                                        }
                                    }
                                } else if (f_demand == Q) {
                                    if (w.size() > 0) {
                                        PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                        //sum_time += time;
                                        continue car;
                                    } else { //否则应该判断一下 RU中的节点数目

                                        PrintRoute.printRoute_w0(RT, RU,w,drone_trip,obj,truck_hub,drone_hub);
                                        //sum_time += time;
                                        break car;
                                    }
                                } else if (f_demand > Q) {
                                    Integer rt__last = RT.get(RT.size() - 1);
                                    RT.remove(rt__last);
                                    w.add(rt__last);
                                    f.remove(rt__last);
                                    RU.add(RT.get(RT.size()-1));
                                    drone_trip = DroneTripUpdate.Method(hub, RU);
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub);
                                    //sum_time += time;

                                    continue car;
                                }
                            } else if (w.size() == 0) {  //如果 所有节点正好全部访问完
                                PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);
                                //sum_time += time;
                                break car;// 跳出大循环
                            }
                        } else if (Ud < D && Uzz < M && Ud < 1.5 * l) {//当选择s中数时  选完一个数需要判断w中节点数 、 f_demand与Q的关系
                            if (w.size() == 0) {
                                PrintRoute.printRoute_w0(RT, RU, w, drone_trip,obj,truck_hub,drone_hub);  //sum_time += time;
                                break car;
                            } else if (w.size() > 0) {
                                int f_demand = Capcity.fD(f);
                                if (f_demand < Q) {
                                    continue sdrone;//当 w中仍有节点且 当前访问节点需求 小于 车辆载重  则继续
                                } else {
                                    w.add(RU.get(RU.size() - 1));
                                    f.remove(RU.get(RU.size() - 1));
                                    RU.remove(RU.size() - 1);
                                    PrintRoute.printRoute(RT, RU, drone_trip,obj,truck_hub,drone_hub); //sum_time += time;
                                    continue car;
                                }
                            }

                        }
                    }
                }
                obj[0] = truck_hub;obj[1] = drone_hub;
                return obj;
    }

    private static ArrayList<Integer> getCustomers(ArrayList<Integer> t1, ArrayList<Integer> d1) {
        //此方法用于提取出t1 和 d1 中所有服务的顾客   写到一个集合里  去个重就可以了
        ArrayList<Integer> al = new ArrayList<>();
        for(int i = 0;i<t1.size();i++) {
            if (!al.contains(t1.get(i))){
                al.add(t1.get(i));
            }
        }
        for(int i = 0;i<d1.size();i++){
            if(!al.contains(d1.get(i))){
                al.add(d1.get(i));
            }
        }
        return al;
    }
}
